package com.rslai.base.tool.servertest.response;

import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;
import org.hamcrest.core.Is;
import org.hamcrest.core.StringContains;
import org.junit.Assert;

import java.io.InputStream;
import java.util.Map;

public class HttpResponse extends Response {
    private Integer status;
    private String callback;
    private Header[] headers;

    public HttpResponse(Integer status, String body, Header[] headers) {
        super(body, null);
        this.status = status;
        this.headers = headers;
    }

    public HttpResponse(Integer status, String body) {
        super(body, null);
        this.status = status;
    }

    public HttpResponse(Integer status, InputStream body, Header[] headers) {
        super(body, null);
        this.status = status;
        this.headers = headers;
    }

    public void verify(Map<String, String> expected) {
        String expectedStatus = (String) expected.get("status");
        assertStatus(expectedStatus);
        assertCallbackFunctionName((String) expected.get("callback"));
        assertHeaders(expected);
        super.verify(expected);
    }

    private void assertHeaders(Map<String, String> expectedHeaders) {
        for (Map.Entry entry : expectedHeaders.entrySet()) {
            String header = (String) entry.getKey();
            if (header.startsWith("header-")) {
                String headerName = header.substring("header-".length());
                String expected = (String) entry.getValue();
                String actual = getHeaderContent(headerName);

                if (StringUtils.isNotBlank(actual))
                    Assert.assertThat("http header " + headerName, actual, StringContains.containsString(expected));
                else if (!expected.equalsIgnoreCase(actual))
                    Assert.fail("期望存在http header " + headerName);
            }
        }
    }

    private void assertCallbackFunctionName(String expectCallback) {
        if (StringUtils.isNotBlank(expectCallback))
            Assert.assertThat("js callback function name is not equals.", this.callback, Is.is(expectCallback));
    }

    private void assertStatus(String expectedStatus) {
        if (StringUtils.isNotBlank(expectedStatus))
            Assert.assertThat("http request status is not equals.", this.status.toString(), Is.is(expectedStatus));
    }

    private String getHeaderContent(String headerName) {
        if (this.headers == null) return "";
        for (int i = 0; i < this.headers.length; i++) {
            if (headerName.equalsIgnoreCase(this.headers[i].getName())) {
                return this.headers[i].getValue();
            }
        }
        return "";
    }

    public void setCallback(String callback) {
        this.callback = callback;
    }

    public String getCallback() {
        return this.callback;
    }

    public Integer getStatus() {
        return this.status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String toString() {
        return "HttpResponse{status=" + this.status + ", body='" + this.body + '\'' + '}';
    }
}
